/*
    SDL - Simple DirectMedia Layer
    Partial implementation of SDL library (originally written by
    Sam Lantinga <slouken@libsdl.org>) for the particular purpose to support
    Prequengine (http://code.google.com/p/prequengine/) on BlackBerry(tm)
    tablets and smartphones.

    Copyright (C) 2013  xlamsp

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

    xlamsp@gmail.com
*/


#include "SDL_pixels.h"


/*
 * Allocate a pixel format structure and fill it according to the given info.
 */
SDL_PixelFormat *SDL_AllocFormat(int bpp,
    Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
    SDL_PixelFormat *format;

    SDL_Log(DEBUG1, "bpp=%d Rmask=0x%x Gmask=0x%x Bmask=0x%x Amask=0x%x",
            bpp, Rmask, Gmask, Bmask, Amask);

    /* Allocate an empty pixel format structure */
    format = SDL_calloc(1, sizeof(*format));
    if(format == NULL) {
        SDL_Log(ERROR, "failed to allocate %d bytes for pixel format!", sizeof(*format));
        return (NULL);
    }
    format->alpha = SDL_ALPHA_OPAQUE;

    /* Set up the format */
    format->BitsPerPixel = bpp;
    format->BytesPerPixel = (bpp + 7) / 8;

    if(bpp <= 8) { /* Palettized mode */
        int ncolors = 1 << bpp;
        format->palette = (SDL_Palette *)SDL_malloc(sizeof(SDL_Palette));
        if(format->palette == NULL) {
            SDL_Log(ERROR, "failed to allocate %d bytes for palette!", sizeof(SDL_Palette));
            SDL_FreeFormat(format);
            return (NULL);
        }
        (format->palette)->ncolors = ncolors;
        (format->palette)->colors = (SDL_Color *)SDL_malloc(
                (format->palette)->ncolors * sizeof(SDL_Color));
        if((format->palette)->colors == NULL) {
            SDL_Log(ERROR, "failed to allocate %d bytes for the palette colors!",
                (format->palette)->ncolors * sizeof(SDL_Color));
            SDL_FreeFormat(format);
            return (NULL);
        }
    } else {
        format->palette = NULL;
    }

    SDL_Log(DEBUG1, "allocated format=0x%p", format);
    return (format);
}

/*
 * Free a previously allocated format structure
 */
void SDL_FreeFormat(SDL_PixelFormat *format)
{
    SDL_Log(DEBUG1, "entered, format=0x%p", format);

    if(format) {
        if(format->palette) {
            if(format->palette->colors) {
                SDL_free(format->palette->colors);
            }
            SDL_free(format->palette);
        }
        SDL_free(format);
    }
}

/*
 * Calculate the pad-aligned scanline width of a surface
 */
Uint16 SDL_CalculatePitch(SDL_Surface *surface)
{
    Uint16 pitch;

    /* Surface should be 4-byte aligned for speed */
    pitch = surface->w * surface->format->BytesPerPixel;
    switch(surface->format->BitsPerPixel) {
        case 1:
            pitch = (pitch + 7) / 8;
            break;
        case 4:
            pitch = (pitch + 1) / 2;
            break;
        default:
            break;
    }
    pitch = (pitch + 3) & ~3; /* 4-byte aligning */

    SDL_Log(DEBUG1, "surface=0x%p width=%d bpp=%d => pitch=%d",
        surface, surface->w, (Uint32)(surface->format->BitsPerPixel), (Uint32)pitch);
    return (pitch);
}


